package com.example.commons.util;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class PageConverterUtil {

    /**
     * 将一个Page<T>对象转换为Page<V>对象。
     *
     * @param sourcePage 源Page对象，包含分页信息和记录列表
     * @param targetClass 目标对象的类类型
     * @param <T> 源记录的类型
     * @param <V> 目标记录的类型
     * @return 转换后的Page<V>对象
     */
    public static <T, V> Page<V> convertPage(Page<T> sourcePage, Class<V> targetClass) {
        // 创建一个新的Page对象，复制源Page的分页信息
        Page<V> targetPage = new Page<>(sourcePage.getCurrent(), sourcePage.getSize(), sourcePage.getTotal());
        // 获取源Page中的记录列表
        List<T> sourceList = sourcePage.getRecords();
        // 创建一个新的列表，用于存储转换后的目标对象
        List<V> targetList = new ArrayList<>();

        // 遍历源记录列表，将每个源对象转换为目标对象
        for (T source : sourceList) {
            V target =copyProperty(source, targetClass);
            targetList.add(target);
        }

        // 将转换后的目标对象列表设置到目标Page中
        targetPage.setRecords(targetList);
        return targetPage;
    }


    /**
     * 将List手动分页
     * @param list
     * @param
     * @return
     */
    public static<T> Page<T> page(List<T> list, int current, int size) {
        if (list.size()<=(current-1)*size) {
            throw new IllegalArgumentException("页码输入有误");
        }
        Page<T> page = new Page<>(current, size);
        page.setTotal(list.size());
        if(list.size()>(current-1)*size){
            int index = Math.min(list.size(), current * size);
            page.setRecords(list.subList((current - 1) * size,  index));
        } else{
            page.setRecords(list);
        }
        return page;
    }

    /**
     * 复制List
     * @param sourceList
     * @param targetClass
     * @return
     * @param <T>
     * @param <U>
     * @throws Exception
     */
    public static <T, U> List<U> copyList(List<T> sourceList, Class<U> targetClass)  {
        List<U> targetList = new ArrayList<>();
        for (T source : sourceList) {
            U target=copyProperty(source, targetClass);
            targetList.add(target);
        }
        return targetList;
    }

    /**
     * 复制对象相同的字段
     * @param source
     * @param clazz
     * @return
     * @param <T>
     */
    public static <T> T copyProperty(Object source, Class<T> clazz) {
        try {
            T target = clazz.newInstance();
            for (Field field : source.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                for (Field field1 : clazz.getDeclaredFields()) {
                    field1.setAccessible(true);
                    if (field1.getName().equals(field.getName()) && field.getType().equals(field1.getType())) {
                        field1.set(target, field.get(source));
                    }
                }

            }
            return target;
        } catch (Exception e) {
            throw new RuntimeException("copy property error", e);
        }
    }

}

